﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GSBA.Common;
using System.ComponentModel;
using Windows.Storage;
using System.Collections.ObjectModel;
using Bing.Maps;
using Windows.UI;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml;

namespace GSBA.ViewModels
{

    public class MapItemDataTemplateSelector : DataTemplateSelector
    {
        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            return (DataTemplate)Application.Current.Resources["ItemTemplate"];
        }
    } 


    public class CategoryListingViewModel : ViewModelBase
    {
        //TODO:Need this to define CollectionViewSource
        public CategoryListingViewModel() : base()
        {
            this.BackNavigationCommand = new NavigationCommand<object>((o) => NavigationService.GetInstance().GoBack());

            this.CategoryTitle = "Sample Title";

            this.BusinessWithLocations = new ObservableCollection<BusinessTile>();
            this.CategoryList = new ObservableCollection<BusinessTile>();

            if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
            {
                this.PopulateSampleData();
            }

            this.MapCenter = new Location(47.609722, -122.333056);


        }

        public CategoryListingViewModel(string category, StorageFile file) : this()
        {
            if (category == null)
            {
                throw new ArgumentNullException("Category null");
            }

            this.CategoryTitle = category;

            this.GetCategoryData(file);
        }

        private Location _mapCenter;
        public Location MapCenter
        {
            get
            {
                return _mapCenter;
            }
            set
            {
                _mapCenter = value;
                RaisePropertyChanged("MapCenter");
            }
        }



        private void PopulateSampleData()
        {
            for (int i = 0; i != 3; ++i)
            {
                var businessTile = new BusinessTile("Restaurant " + i,"John", "Address "+i+"th street", new Tuple<string,string>("0","0"), "test@test.com", "www.test.com", "+123");
                this.CategoryList.Add(businessTile);
            }
        }

        private async void GetCategoryData(StorageFile file)
        {
            // TODO Fill in data here for CategoryTitle
            var lineCount = 0;
            var readFile = await Windows.Storage.FileIO.ReadLinesAsync(file);
            char[] separator = new char[] { ',' };
            var categoryList = new List<BusinessTile>();

            foreach (var line in readFile)
            {
                if (lineCount++ == 0)
                    continue;

                var colVal = CsvLib.ParseCsvRow(line);
                if (colVal.Length > 17)
                {
                    var categoryName = colVal[17];
                    string address = CreateFullAddress(colVal[6], colVal[7], colVal[8], colVal[9]);
                    categoryList.Add(new BusinessTile(colVal[4], colVal[5], address, new Tuple<string, string>(colVal[10], colVal[11]), colVal[12], colVal[16], colVal[13]));
                }
            }

            this.CategoryList = new ObservableCollection<BusinessTile>(categoryList);
        }

        private string CreateFullAddress(string p1, string p2, string p3, string p4)
        {
            string result = string.Empty;
            if (!string.IsNullOrEmpty(p1))
            {
                result += p1;
                if (!string.IsNullOrEmpty(p2))
                {
                    result += ", ";
                }
            }
            if (!string.IsNullOrEmpty(p2))
            {
                result += p2;
                if (!string.IsNullOrEmpty(p3))
                {
                    result += ", ";
                }
            }
            result += p3 + " " + p4;
            return result;
        }

        public NavigationCommand<object> BackNavigationCommand
        {
            get;
            set;
        }

        public string CategoryTitle
        {
            get;
            set;
        }

        private ObservableCollection<BusinessTile> categoryList;
        public ObservableCollection<BusinessTile> CategoryList
        {
            get
            {
                return categoryList;
            }
            set
            {
                categoryList = value;
                RaisePropertyChanged("CategoryList");
            }
        }

        private ObservableCollection<BusinessTile> businessWithLocations;
        public ObservableCollection<BusinessTile> BusinessWithLocations
        {
            get
            {
                return businessWithLocations;
            }
            set
            {
                businessWithLocations = value;
                RaisePropertyChanged("BusinessWithLocations");
            }
        }

        private BusinessTile selectedBusiness;
        public BusinessTile SelectedBusiness
        {
            get
            {

                return selectedBusiness;
            }
            set
            {
                selectedBusiness = value;
                if (this.IsValidPosition(selectedBusiness.Position.Item1, selectedBusiness.Position.Item2))
                {
                    var latitude = Double.Parse(selectedBusiness.Position.Item1);
                    var longitude = Double.Parse(selectedBusiness.Position.Item2);
                    this.MapCenter = new Location(latitude, longitude);
                }

                RaisePropertyChanged("SelectedBusiness");
            }
        }

        void OnRefresh(object obj)
        {
        }

        protected override void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "CategoryList")
            {
                this.BusinessWithLocations.Clear();
                var firstBusinessWithLocation = this.CategoryList.Where(x => x.Position != null && this.IsValidPosition(x.Position.Item1, x.Position.Item2)).FirstOrDefault();
                if (firstBusinessWithLocation != null)
                {
                    this.BusinessWithLocations.Add(firstBusinessWithLocation);
                }
            }
            else if (e.PropertyName == "SelectedBusiness")
            {

                this.BusinessWithLocations.Clear();
                if (selectedBusiness.Position != null && this.IsValidPosition(selectedBusiness.Position.Item1, selectedBusiness.Position.Item2))
                {
 
                    this.BusinessWithLocations.Add(selectedBusiness);
                }
            }
        }

        private bool IsValidPosition(string latitude, string longitude)
        {
            return !string.IsNullOrEmpty(latitude) && !string.IsNullOrEmpty(longitude) && latitude != "0" && longitude != "0";
        }
    }

    public class BusinessTile
    {
        public BusinessTile(string name, string person, string address, Tuple<string,string> position, string email, string website, string phone)
        {
            this.Name = name;
            this.Person = person;
            this.Address = address;
            this.Position = position;
            this.Email = email;
            this.WebSite = website;
            this.Phone = phone;
            this.LinkCommand = new NavigationCommand<object>((o) => NavigationService.GetInstance().NavigateUri(this.WebSite));
            this.PhoneCommand = new NavigationCommand<object>((o) => NavigationService.GetInstance().MakeCall(this.Phone));
            this.EmailCommand = new NavigationCommand<object>((o) => NavigationService.GetInstance().SendMail(this.Email));
        }

        public string Name
        {
            get;
            set;
        }

        public string Address
        {
            get;
            set;
        }

        public string Person
        {
            get;
            set;
        }

        public string Email
        {
            get;
            set;
        }

        public string WebSite
        {
            get;
            set;
        }

        public string Phone
        {
            get;
            set;
        }

        public NavigationCommand<object> LinkCommand
        {
            get;
            set;
        }

        public NavigationCommand<object> PhoneCommand
        {
            get;
            set;
        }

        public NavigationCommand<object> EmailCommand
        {
            get;
            set;
        }

        public Tuple<string,string> Position
        {
            get;
            set;
        }

        public bool IsAddressVisible
        {
            get
            {
                return !string.IsNullOrEmpty(this.Address.Trim());
            }
        }

        public bool IsPhoneVisible
        {
            get
            {
                return !string.IsNullOrEmpty(this.Phone);
            }
        }

        public bool IsWebsiteLinkVisible
        {
            get
            {
                return !string.IsNullOrEmpty(this.WebSite);
            }
        }

        public bool IsPersonVisible
        {
            get
            {
                return !string.IsNullOrEmpty(this.Person);
            }
        }

        public bool IsEmailVisible
        {
            get
            {
                return !string.IsNullOrEmpty(this.Email);
            }
        }
    }
}